﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Working.Domínio.Instrumentação
{
    sealed class CacheDeEntidades
    {
        private Dictionary<Type, Dictionary<int, Entidade>> cache;

        public CacheDeEntidades()
        {
            cache = new Dictionary<Type, Dictionary<int, Entidade>>();
        }

        public void AdicionarEntidade<T>(Entidade entidade) where T: Entidade
        {
            Dictionary<int, Entidade> entidadesRelacionadas;
            Type type = typeof(T);
            if(entidade != null)
            {
                cache.TryGetValue(type, out entidadesRelacionadas);
                if(entidadesRelacionadas == null)
                {
                    entidadesRelacionadas = new Dictionary<int, Entidade>();
                    cache.Add(type, entidadesRelacionadas);
                }

                if(entidadesRelacionadas.ContainsKey(entidade.OID))
                    entidadesRelacionadas[entidade.OID] = entidade;
                else
                    entidadesRelacionadas.Add(entidade.OID, entidade);
            }
            else
            {
                throw new ArgumentException(string.Format("Parâmetro entidade não referencia uma instância de um objeto '{0}'",
                    type.Name), "entidade");
            }
        }

        public T ObterEntidade<T>(int oid) where T: Entidade
        {
            Entidade entidade = null;            
            Dictionary<int, Entidade> entidadesRelacionadas;
            Type type = typeof(T);

            if(oid > 0)
            {                
                if(cache.ContainsKey(type))
                {
                    entidadesRelacionadas = cache[type];
                    entidadesRelacionadas.TryGetValue(oid, out entidade);
                }
            }
            else
            {
                throw new ArgumentException(string.Format("Identificador da entidade {0} não pode ser nulo ou vazio.",
                    type.Name), "oid");
            }

            return (T)entidade;
        }
    }
}
